package cn.edu.zjgsu.security;

import cn.edu.zjgsu.dao.AuthorMapper;
import cn.edu.zjgsu.dao.AuthorSecurityViewMapper;
import cn.edu.zjgsu.dao.PermissionMapper;
import cn.edu.zjgsu.dao.RoleMapper;
import cn.edu.zjgsu.model.*;
import org.apache.catalina.User;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * User: wqmei
 * Date: 2017/10/17
 * Time: 18:01
 */
@Component
public class Realm extends AuthorizingRealm
{
    private static final Logger logger = LoggerFactory.getLogger(Realm.class);

    @Autowired
    private AuthorMapper authorMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 检验,用于权限校验
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
    {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        String loginName = principalCollection.fromRealm(getName()).iterator().next().toString();
        if (loginName == null || loginName.length() == 0)
        {
            logger.info("校验权限是用户名为空");
            return info;
        }

        RoleExample roleExample = new RoleExample();
        roleExample.or().andLoginNameEqualTo(loginName);
        List<Role> roles = roleMapper.selectByExample(roleExample);
        if (roles.size() == 0)
        {
            return info;
        }

        //添加角色
        List<String> roleList = new ArrayList<>();
        for (int i=0,length = roles.size(); i<length;i++)
        {
            roleList.add(roles.get(i).getRoleName());
        }
        info.addRoles(roleList);

        //添加权限
        PermissionExample permissionExample = new PermissionExample();
        permissionExample.or().andRoleNameIn(roleList);
        List<Permission> permissions = permissionMapper.selectByExample(permissionExample);
        for (int i=0,length = permissions.size();i<length;i++)
        {
            info.addStringPermission(permissions.get(i).getPermissionName());
        }

        return info;
    }

    /**
     * 验证,用于登录
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException
    {
        System.out.println("====================");
        System.out.println("尝试登陆");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String loginName = token.getUsername();
        if(loginName==null)
        {
            logger.error("登入输入用户名为空");
            throw new AccountException("loginName is null");
        }
        String loginPwd = new String(token.getPassword());
        /**
         * 此处应有加密流程,后期添加,也可以将加密流程置于外部
         */

        AuthorExample authorExample = new AuthorExample();
        authorExample.or().andLoginNameEqualTo(loginName).andLoginPwdEqualTo(loginPwd);
        int resultCount = (int) authorMapper.countByExample(authorExample);
        if(resultCount==1)
        {
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(loginName,loginPwd,this.getName());
            logger.info("用户名为 "+loginName+" 的用户登录");
            return simpleAuthenticationInfo;
        }else
        {
            authorExample.or().andLoginNameEqualTo(loginName);
            int hasThisAuthor = (int) authorMapper.countByExample(authorExample);
            if (hasThisAuthor == 1)
            {
                logger.info("用户名为 "+loginName+" 的用户输入了错误的密码");
                throw new IncorrectCredentialsException("password is wrong");
            }else
            {
                throw new UnknownAccountException("no account for this user");
            }
        }
    }
}
